package com.currentbp.Interesting.likou.complete;

import com.currentbp.util.all.StringUtil;
import org.junit.Test;

/**
 * @author baopan
 * @createTime 2024/3/26 21:10
 */
public class T1493longestSubarray {
    /*
给你一个二进制数组 nums ，你需要从中删掉一个元素。
请你在删掉元素的结果数组中，返回最长的且只包含 1 的非空子数组的长度。
如果不存在这样的子数组，请返回 0 。
提示 1：
输入：nums = [1,1,0,1]
输出：3
解释：删掉位置 2 的数后，[1,1,1] 包含 3 个 1 。
示例 2：
输入：nums = [0,1,1,1,0,1,1,0,1]
输出：5
解释：删掉位置 4 的数字后，[0,1,1,1,1,1,0,1] 的最长全 1 子数组为 [1,1,1,1,1] 。
示例 3：
输入：nums = [1,1,1]
输出：2
解释：你必须要删除一个元素。
     */
    /*
    解题思路：
    1、将所有为1的累加起来，所有为0的变为-1*N，组成一个数组，如【3，-2,4，-5,7】
    2、统计最大数
    2.1、如果数组中有-1，则统计-1周围数字的和  和  数组中其他的正数谁的最大
    2.2、如果没有-1，则判断是否存在负数，
    2.2.1、如果存在负数，则直接获取最大数
    2.2.2、如果不存在负数，则将最小的数字减1，然后获取最大的数字

     */
    /*
    解题思路2：
    1、数组f[x]表示删除第x的最大数量
     */
    @Test
    public void t1() {
        System.out.println(longestSubarray(new int[]{1, 1, 0, 1}));
        System.out.println(longestSubarray(new int[]{0, 1, 1, 1, 0, 1, 1, 0, 1}));
        System.out.println(longestSubarray(new int[]{1, 1, 1}));
        System.out.println(longestSubarray(new int[]{0, 0, 0}));
        System.out.println(longestSubarray(new int[]{0}));
    }

    public int longestSubarray(int[] nums) {
        if (nums == null || nums.length <= 0) {
            return 0;
        }
        int[] newNums = getZips(nums);
//        StringUtil.printObject(newNums);

        if (hasF1(newNums)) {
            return strategy1(newNums);
        }

        if (hasF(newNums)) {
            return strategy2(newNums);
        }

        if (nums[0] < 0) {
            return 0;
        }
        return newNums[0] - 1;
    }

    /**
     * 有其他负数的情况下，直接找最大值
     */
    private int strategy2(int[] newNums) {
        int tempMax = 0;
        for (int i = 0; i < newNums.length; i++) {
            tempMax = tempMax > newNums[i] ? tempMax : newNums[i];
        }
        return tempMax;
    }

    /*
    去掉-1后的最长长度
     */
    private int strategy1(int[] newNums) {
        int tempMax = 0;
        for (int i = 0; i < newNums.length; i++) {
            tempMax = tempMax > newNums[i] ? tempMax : newNums[i];
        }

        for (int i = 1; i < newNums.length - 1; i++) {
            if (newNums[i] == -1) {
                tempMax = tempMax > (newNums[i - 1] + newNums[i + 1]) ? tempMax : (newNums[i - 1] + newNums[i + 1]);
            }
        }

        return tempMax;
    }

    private boolean hasF(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < 0) {
                return true;
            }
        }
        return false;
    }

    private boolean hasF1(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            if (-1 == nums[i]) {
                return true;
            }
        }
        return false;
    }

    private int[] getZips(int[] nums) {
        int[] result = new int[nums.length];

        int index = 0;
        boolean flag = nums[0] > 0;//为1的标记
        int count = nums[0] > 0 ? 1 : -1;
        for (int i = 1; i < nums.length; i++) {
            if (flag) {
                if (nums[i] == 1) {
                    count++;
                } else {
                    result[index] = count;
                    index++;
                    count = -1;
                    flag = !flag;
                }
            } else {
                if (nums[i] == 0) {
                    count--;
                } else {
                    result[index] = count;
                    index++;
                    count = 1;
                    flag = !flag;
                }
            }
        }
        result[index] = count;

        int newLen = result.length;
        for (int i = 0; i < result.length; i++) {
            if (result[i] == 0) {
                newLen = i;
                break;
            }
        }
        int[] newResult = new int[newLen];
        for (int i = 0; i < newLen; i++) {
            newResult[i] = result[i];
        }

        return newResult;
    }
}
